package service

import (
	"awesomeProject/app/model"
	"awesomeProject/app/request"
	"awesomeProject/app/response"
	"awesomeProject/global"
	"awesomeProject/util"
	"fmt"
	"github.com/fatih/structs"
)

type AccountSrv struct{}

var hostSrv HostSrv

func (r *AccountSrv) Pagination(req request.AccountPagination, operator model.User) response.Resp {
	offset := (req.PageIndex - 1) * req.PageSize
	where := "1=1"
	if req.CompanyId == 0 {
		if operator.CompanyId != 0 {
			where += fmt.Sprintf(" and company_id=%d", operator.CompanyId)
		}
		//companyIds := util.GetUserCompanyIds(operator)
		//if len(companyIds) > 0 {
		//	where += fmt.Sprintf(" and `company_id` in (%s)", util.UintsToStr(companyIds, ","))
		//}
	}
	if req.Username != "" {
		where += " AND (`username` LIKE '%" + req.Username + "%')"
	}
	if req.ShopID != "" {
		where += " AND `shop_id`=" + req.ShopID
	}
	if req.Status != nil && (*req.Status == 0 || *req.Status == 1) {
		where += fmt.Sprintf(" AND `status`=%d", *req.Status)
	}
	if req.CompanyId != 0 {
		where += fmt.Sprintf(" AND `company_id`=%d", req.CompanyId)
	}
	if req.Keyword != "" {
		where += " and (`fordeal_shop_name` like '%" + req.Keyword +
			"%' or `shop_name` like '%" + req.Keyword +
			"%' or `fordeal_shop_name_en` like '%" + req.Keyword + "%')"
	}
	//user := userSrv.FindByID(operator.ID, operator.CompanyId)
	if !operator.SuperAdmin {
		if len(operator.ShopIds) > 0 {
			shopIdStr := util.ArrrayUintJoin(operator.ShopIds, ",")
			where += fmt.Sprintf(" and `shop_id` in (%s)", shopIdStr)
		}
	}
	// 非超级管理员账号过滤掉admin店铺账号展示
	if operator.Username != "admin" {
		where += " AND `username` != 'admin'"
	}
	var accounts []model.Account
	err := global.Gorm.Where(where).Offset(offset).Limit(req.PageSize).Find(&accounts).Error
	if err != nil {
		return response.ErrQuery
	}
	if len(accounts) == 0 {
		return response.OK.WithData(map[string]interface{}{
			"total": 0,
			"list":  accounts,
		})
	}

	var companies []model.Company
	err = global.Gorm.Find(&companies).Error
	if err != nil {
		return response.ErrQuery
	}
	kc := make(map[uint]string)
	for _, company := range companies {
		companyName := kc[company.ID]
		if len(companyName) > 0 {
			continue
		}
		kc[company.ID] = company.CompanyName
	}

	for i, account := range accounts {
		companyName := kc[uint(account.CompanyId)]
		if len(companyName) > 0 {
			accounts[i].CompanyName = companyName
		} else {
			accounts[i].CompanyName = "-"
		}
	}

	var total int64
	err = global.Gorm.Model(&model.Account{}).Where(where).Count(&total).Error
	if err != nil {
		return response.ErrQuery
	}

	return response.OK.WithData(map[string]interface{}{
		"total": total,
		"list":  accounts,
	})
}

func (r *AccountSrv) FindByID(id uint, operator model.User) (error, model.Account) {
	var account model.Account
	where := "1=1"
	if operator.CompanyId != 0 {
		where += fmt.Sprintf(" and company_id=%d", operator.CompanyId)
	}
	err := global.Gorm.Where("id = ?", id).Where(where).First(&account).Error

	return err, account
}

func (r *AccountSrv) FindByUsername(username string) (error, model.Account) {
	var account model.Account
	err := global.Gorm.Where("username = ?", username).First(&account).Error

	return err, account
}

func (r *AccountSrv) Update(id uint, req request.AccountUpdate, operator model.User) response.Resp {
	err, account := r.FindByID(id, operator)
	if err != nil {
		return response.ErrQuery.SetMsg(err.Error())
	}
	if account.ID == 0 {
		return response.ErrRecordNotFound
	}
	updates := structs.Map(req)
	if err = global.Gorm.Model(&account).Updates(updates).Error; err != nil {
		return response.ErrStore.SetMsg(err.Error())
	}
	// 更新关联主机记录表里的店铺密码信息
	if req.Username != "" && req.Password != "" && req.OriginPwd != "" {
		err, host := hostSrv.FindByHostAccountUsername(account.Username)
		// 检查有没有关联主机，有则更新关联主机
		if err == nil &&  host.ID > 0{
			hostAccountFillAble := model.HostAccountFillAble{
				AccountUsername: req.Username,
				AccountPassword: req.Password,
				AccountOriginPwd: req.OriginPwd,
			}
			hostSrv.UpdateHostAccountPassword(req.Username, hostAccountFillAble)
		} else {   // 检查有没有关联主机，没有则创建一条关联主机
			hostAccountFillAble := model.HostAccountFillAble{
				AccountUsername: account.Username,
				AccountPassword: account.Password,
				AccountOriginPwd: account.OriginPwd,
			}
			hostSrv.CreateHostByAccount(hostAccountFillAble)
		}
	}
	return response.OK
}

func (r *AccountSrv) Create(account model.AccountFillAble, operator model.User) response.Resp {
	if operator.CompanyId != 0 {
		account.CompanyId = operator.CompanyId
	}
	accountObj := model.Account{
		AccountFillAble: account,
	}
	if err := global.Gorm.Model(&model.Account{}).Create(&accountObj).Error; err != nil {
		return response.ErrCreate.SetMsg(err.Error())
	}
	// 更新关联主机记录表里的店铺密码信息
	if account.Username != "" && account.Password != "" && account.OriginPwd != "" {
		hostAccountFillAble := model.HostAccountFillAble{
			AccountUsername: account.Username,
			AccountPassword: account.Password,
			AccountOriginPwd: account.OriginPwd,
		}
		hostSrv.UpdateHostAccountPassword(account.Username, hostAccountFillAble)
	}
	// 检查有没有关联主机，没有则创建一条关联主机
	if account.Username != "" && account.Password != "" && account.OriginPwd != "" {
		err, host := hostSrv.FindByHostAccountUsername(account.Username)
		// 检查有没有关联主机，有则更新关联主机
		if err == nil &&  host.ID > 0{
			hostAccountFillAble := model.HostAccountFillAble{
				AccountUsername: account.Username,
				AccountPassword: account.Password,
				AccountOriginPwd: account.OriginPwd,
			}
			hostSrv.UpdateHostAccountPassword(account.Username, hostAccountFillAble)
		} else {   // 检查有没有关联主机，没有则创建一条关联主机
			hostAccountFillAble := model.HostAccountFillAble{
				AccountUsername: account.Username,
				AccountPassword: account.Password,
				AccountOriginPwd: account.OriginPwd,
			}
			hostSrv.CreateHostByAccount(hostAccountFillAble)
		}
	}
	return response.OK
}

func (r *AccountSrv) Del(id uint, operator model.User) response.Resp {
	err, account := r.FindByID(id, operator)
	if err != nil {
		return response.ErrQuery.SetMsg(err.Error())
	}
	if account.ID == 0 {
		return response.ErrRecordNotFound
	}
	// 数据删除
	if err := global.Gorm.Unscoped().Delete(&account).Error; err != nil {
		return response.ErrDel.SetMsg(err.Error())
	}
	// 删除关联主机记录
	err, host := hostSrv.FindByHostAccountUsername(account.Username)
	if err == nil &&  host.ID > 0{
		hostSrv.Del(host.ID)
	}
	return response.OK
}

func (r *AccountSrv) UpdatePassword(username string, accountPasswordFillAble model.AccountPasswordFillAble) response.Resp {
	err, account := r.FindByUsername(username)
	if err != nil {
		return response.ErrQuery.SetMsg(err.Error())
	}
	if account.ID == 0 {
		return response.ErrRecordNotFound
	}
	updates := structs.Map(accountPasswordFillAble)
	if err = global.Gorm.Model(&account).Updates(updates).Error; err != nil {
		return response.ErrStore.SetMsg(err.Error())
	}
	return response.OK
}

func (r *AccountSrv) GetHashPwd(OriginPwd string) (string, error) {
	hashPwd, err := util.FordealEncrypt(OriginPwd)
	return hashPwd, err
}

func (r *AccountSrv) GetAccount(Username string) (error, model.Account) {
	err, account := r.FindByUsername(Username)
	return err, account
}
